package com.googlecode.dgwt.client.dojox.data.base;

import java.util.Collections;
import java.util.List;
import java.util.Set;

import com.googlecode.dgwt.client.dijit.View;
import com.googlecode.dgwt.client.dojo.callback.SimpleCallback;
import com.googlecode.dgwt.client.dojo.callback.VoidCallback;
import com.googlecode.dgwt.client.dojo.data.base.IndexedStore;
import com.googlecode.dgwt.client.dojo.data.base.ModeledStoreBase;
import com.googlecode.dgwt.client.dojo.data.base.Store;
import com.googlecode.dgwt.client.dojo.data.base.TableStore;
import com.googlecode.dgwt.client.dojo.data.listener.AttachListener;
import com.googlecode.dgwt.client.dojo.data.listener.DataListener;
import com.googlecode.dgwt.client.dojo.data.listener.ModelListener;
import com.googlecode.dgwt.client.dojo.data.listener.StoreListener;
import com.googlecode.dgwt.client.dojo.data.model.StoreColumn;
import com.googlecode.dgwt.client.dojo.data.model.StoreColumnBase;
import com.googlecode.dgwt.client.dojo.data.model.StoreModel;
import com.googlecode.dgwt.client.dojo.exception.ValidationException;
import com.googlecode.dgwt.client.dojox.data.model.DataColumn;
import com.googlecode.dgwt.client.dojox.data.model.DataModel;

/**
 * A read-only implementation of store for general usage.
 * 
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class EmptyStore<Item> extends ModeledStoreBase<Item,DataModel<Item>,DataColumn<Item,?>> 
                              implements NamedStore<Item>, GridStore<Item> {

    private static EmptyStore<?> emptyStore;
    private static StoreColumn<Object,?> emptyColumn;
    
    private DataModel<Item> model = new DataModel<Item>() {

        @Override
        protected ColumnList createColumnList(int initialCapacity) {
            return new ColumnList(0) {

                @Override
                protected void internalAdd(int index, DataColumn<Item, ?> item) {
                    throw new UnsupportedOperationException();
                }

                @Override
                protected DataColumn<Item, ?> internalSet(int index, DataColumn<Item, ?> item) {
                    throw new UnsupportedOperationException();
                }                
            };
        }
    };
    
    
    private EmptyStore() {
    }
    
    
    @SuppressWarnings("unchecked")
    public static <E> EmptyStore<E> get(){
        if (emptyStore == null) {
            emptyStore = new EmptyStore<E>();
        }
        return (EmptyStore<E>) emptyStore;
    }
    
    
    @SuppressWarnings("unchecked")
    public static <Item,Type> StoreColumnBase<Item,Type> getEmptyColumn() {
        if (emptyColumn == null){
            emptyColumn = new DataColumn<Object,Object>(Object.class) {
                @Override
                protected Object onGetValue(Object item) {
                    return null;
                }
                @Override
                protected void onSetValue(Object item, Object value) {
                }
            };
        }
        return (StoreColumnBase<Item, Type>) emptyColumn;
    }

    
    @SuppressWarnings("unchecked")
    public static <Item> DataModel<Item> getEmptyModel(){
        return (DataModel<Item>) get().getModel();
    }
    
    
    @Override
    public int getColumnMaxLength(int fieldIndex) {
        return 0;
    }

    @Override
    public String getColumnTitle(int fieldIndex) {
        return "";
    }

    @Override
    public String getColumnWidth(int columnIndex) {
        return "";
    }

    @Override
    public String getDisplayValue(Item item, int fieldIndex) {
        return "";
    }

    @Override
    public DataModel<Item> getModel() {
        return model;
    }

    @Override
    protected void setModel(DataModel<Item> model) {
        throw new UnsupportedOperationException();
    }


    @Override
    public Object getValue(Item item, int fieldIndex) {
        return null;
    }

    @Override
    public boolean setValue(Item item, int fieldIndex, Object value) {
        return false;
    }

    @Override
    public Item get(int index) {
        throw new ArrayIndexOutOfBoundsException(index);
    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public void fetch(int index, int count, VoidCallback callback) {
        callback.callback();
    }

    @Override
    public void fetch(int index, int count, SimpleCallback<List<Item>> callback) {
        callback.callback(this);
    }

    @Override
    public Object getValue(Item item, String fieldName) {
        return null;
    }

    @Override
    public boolean setValue(Item item, String fieldName, Object value) {
        return false;
    }

    @Override
    public void setDisplayValue(Item item, int fieldIndex, String value) {
    }

    @Override
    public void refreshValue(Item item, int fieldIndex) {
    }

    @Override
    public void refreshItem(Item item) {
    }

    @Override
    public void refreshItem(int rowIndex) {
    }

    @Override
    public void refreshValue(int rowIndex, int fieldIndex) {
    }

    @Override
    public Set<DataListener<Item>> getDataListeners() {
        return Collections.emptySet();
    }

    @Override
    public Set<ModelListener<Item>> getModelListeners() {
        return Collections.emptySet();
    }

    @Override
    public boolean isReadOnly() {
        return true;
    }

    @Override
    public boolean replace(Item curItem, Item newItem) {
        return false;
    }

    @Override
    public void refresh() {
    }

    @Override
    public boolean addListener(StoreListener<Item> listener) {
        return false;
    }

    @Override
    public boolean addListener(DataListener<Item> listener) {
        return false;
    }

    @Override
    public boolean addListener(ModelListener<Item> listener) {
        return false;
    }

    @Override
    public boolean hasListener(AttachListener<?> listener) {
        return false;
    }

    @Override
    public boolean removeListener(AttachListener<?> listener) {
        return false;
    }

    @Override
    public IndexedStore<Item> createMirror() {
        return this;
    }

    @Override
    public TableStore<Item> createMirror(StoreModel<Item, ?> model) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Store<Item> cloneStore() {
        return this;
    }


    @Override
    public Store<Item> append(Item item) {
        return this;
    }


    @Override
    public Item addNew() {
        return null;
    }


    @Override
    public void refreshColumnValues(int columnIndex) {
    }


    @Override
    public void setDisplayValues(Item item, String... valueList) throws ValidationException {
    }


    @Override
    public Item findByValues(Object... columnValues) {
        return null;
    }


    @Override
    public int indexOfValues(Object... columnValues) {
        return -1;
    }


    @Override
    public Item findByDisplayValues(String... columnValues) {
        return null;
    }


    @Override
    public int indexOfDisplayValues(String... columnValues) {
        return -1;
    }


    @Override
    public Item findByValues(int startColumnIndex, Object... columnValues) {
        return null;
    }


    @Override
    public int indexOfValues(int startColumnIndex, Object... columnValues) {
        return -1;
    }


    @Override
    public Item addNew(int rowIndex) {
        return null;
    }


    @Override
    public Item findByDisplayValues(int startColumnIndex, String... columnValues) {
        return null;
    }


    @Override
    public int indexOfDisplayValues(int startColumnIndex, String... columnValues) {
        return -1;
    }


    @Override
    public boolean modified(Item item) {
        return false;
    }


    @Override
    public Set<View> getParents() {
        return Collections.emptySet();
    }


    @Override
    public boolean hasParent(View parentView) {
        return false;
    }


    @Override
    public boolean registerParent(View parentView) {
        return false;
    }


    @Override
    public boolean unregisterParent(View parentView) {
        return false;
    }


    @Override
    protected Class<?> getModelBaseClass() {
        return DataModel.class;
    }

}
